﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Diagnostics;

namespace CGShaderIntegration.DrawableGameComponents
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class SlimeneTaycirShader : Microsoft.Xna.Framework.DrawableGameComponent, IMatrices
    {

        //////////////////////////////////////////////////////////////////////
        // componenten

        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        ContentManager Content;

        // model
        Model moon_, earth_, sun_;

        // model's matrix
        Matrix worldMatrix, viewMatrix, projectionMatrix;

        // model's speed
        double earth_rotation, moon_rotation, camera_rotation;
        float range_earth, range_moon, range_camera;

        // model's shader-effects
        Effect effect_;

        float x1, x2, y1, y2, x_view, y_view, z_view, val_view;

        public SlimeneTaycirShader(Game game)
            : base(game)
        {
            // TODO: Construct any child components here
            game.Components.Add(this);
            Content = game.Content;

            range_earth = 2f;
        }

        public override void Initialize()
        {
            // TODO: Add your initialization code here

            base.Initialize();

            viewMatrix = Matrix.CreateLookAt(
            new Vector3(0, 0, 10),
            new Vector3(0.0f, 0.0f, 0.0f),
            Vector3.Up);

            x_view = y_view = 0;
            z_view = 15;
        }

        protected override void LoadContent()
        {
            sun_ = Content.Load<Model>("Models\\earth");
            moon_ = Content.Load<Model>("Models\\earth");
            earth_ = Content.Load<Model>("Models\\earth");

            //effect
            effect_ = Content.Load<Effect>("effects\\SlimeneTaycir_schachbrett");
        }

        protected override void UnloadContent()
        { }

        public override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back
                    == ButtonState.Pressed)
            {
                this.Game.Exit();
            }

            // update all values
            moon_rotation -= 0.05f;    //cw
            earth_rotation += 0.01f;    //ccw
        }

        public override void Draw(GameTime gameTime)
        {
            try
            {
                GraphicsDevice.Clear(Color.DimGray);
                // view matrix
                viewMatrix = Matrix.CreateLookAt(
                new Vector3(x_view, y_view, z_view),
                new Vector3(0.0f, 0.0f, 0.0f),
                Vector3.Up);

                // projection matrix
                projectionMatrix = Matrix.CreatePerspectiveFieldOfView(
                MathHelper.ToRadians(90.0f),
                    //MathHelper.PiOver4,
                800.0f / 600.0f,
                1.0f, 100.0f);

                /////////////////////////////////////////
                // sun
                /////////////////////////////////////////
                foreach (ModelMesh mesh in sun_.Meshes)
                {
                    foreach (ModelMeshPart effect in mesh.MeshParts)
                    {
                        //effect.EnableDefaultLighting();
                        //effect.LightingEnabled = true;
                        //if (!is_txtrd) effect.DiffuseColor = new Vector3(1.0f, 1.0f, 1.0f);
                        //effect.World = worldMatrix;
                        //effect.View = viewMatrix;
                        //effect.Projection = projectionMatrix;

                        effect.Effect.Parameters["World"].SetValue(worldMatrix);
                        effect.Effect.Parameters["View"].SetValue(viewMatrix);
                        effect.Effect.Parameters["Projection"].SetValue(projectionMatrix);
                        effect.Effect.Parameters["sclice_wrld"].SetValue(20);
                    }
                    mesh.Draw();
                }

                /////////////////////////////////////////
                // sun
                /////////////////////////////////////////
                foreach (ModelMesh mesh in sun_.Meshes)
                {
                    foreach (BasicEffect effect in mesh.Effects)
                    {
                        effect.EnableDefaultLighting();
                        //effect.LightingEnabled = true;
                        //if (!is_txtrd) effect.DiffuseColor = new Vector3(1.0f, 1.0f, 1.0f);
                        effect.World = worldMatrix;
                        effect.View = viewMatrix;
                        effect.Projection = projectionMatrix;
                    }
                    mesh.Draw();
                }

                /////////////////////////////////////////
                // earth
                /////////////////////////////////////////
                worldMatrix = Matrix.CreateTranslation(
                    new Vector3(range_earth, range_earth, 0.0f))
                    * Matrix.CreateRotationZ((float)earth_rotation);

                foreach (ModelMesh mesh in earth_.Meshes)
                {
                    foreach (ModelMeshPart effect in mesh.MeshParts)
                    {
                        //effect.EnableDefaultLighting();
                        //if (!is_txtrd) effect.DiffuseColor = new Vector3(1.0f, 1.0f, 1.0f);
                        //effect.Effect = effect_;
                        //effect.World = worldMatrix;
                        //effect.View = viewMatrix;
                        //effect.Projection = projectionMatrix;

                        effect.Effect = effect_;
                        effect.Effect.Parameters["World"].SetValue(worldMatrix);
                        effect.Effect.Parameters["View"].SetValue(viewMatrix);
                        effect.Effect.Parameters["Projection"].SetValue(projectionMatrix);
                        effect.Effect.Parameters["sclice_wrld"].SetValue(20);
                    }
                    mesh.Draw();
                }

                /////////////////////////////////////////
                // earth's moon
                /////////////////////////////////////////
                worldMatrix = Matrix.CreateTranslation(
                    new Vector3(0f, 6f, 6f))
                    * Matrix.CreateRotationX((float)moon_rotation * 0.9f)
                    * Matrix.CreateRotationY(-4)
                    ;

                foreach (ModelMesh mesh in moon_.Meshes)
                {
                    foreach (ModelMeshPart effect in mesh.MeshParts)
                    {
                        //effect.EnableDefaultLighting();
                        //effect.LightingEnabled = true;
                        //effect.AmbientLightColor =
                        //    new Vector3(0f, 1, 0f);
                        //effect.World = worldMatrix *
                        //    Matrix.CreateScale(new Vector3(0.5f, 0.5f, 0.5f));
                        //effect.View = viewMatrix;
                        //effect.Projection = projectionMatrix;

                        effect.Effect = effect_;
                        effect.Effect.Parameters["World"].SetValue(worldMatrix);
                        effect.Effect.Parameters["View"].SetValue(viewMatrix);
                        effect.Effect.Parameters["Projection"].SetValue(projectionMatrix);
                        effect.Effect.Parameters["sclice_wrld"].SetValue(20);
                    }
                    mesh.Draw();
                }


            }
            catch (Exception ex)
            {

            }
        }

        //////////////////////////////////////////////////////////////////////

        public Matrix WorldMatrix
        {
            get;
            set;
        }

        public Matrix ViewMatrix
        {
            get;
            set;
        }

        public Matrix ProjectionMatrix
        {
            get;
            set;
        }

        /// <summary>
        /// Return the author´s name
        /// Please use NachnameVorname (without spaces).
        /// </summary>
        /// <returns>author´s name</returns>
        public String GetName()
        {
            return "SlimeneTaycir";
        }

    }
}
